package at.bartinger.gameoflive;

import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

public class GameOfLiveView extends SurfaceView implements SurfaceHolder.Callback{

	private Context context;

	private SurfaceHolder mHolder;
	private GameOfLiveThread mCanvasThread;
	private GameOfLiveUpdater updater = new GameOfLiveUpdater();
	private int cellsize;

	private int sleep = 25;
	
	private boolean eraser = false;

	//toogle Erase function on Long-press
	private long downtime;
	private boolean allowEreaseSwitch = true;
	private int longpressmillis = 900;
	private int lastX;
	private int lastY;
	private int movement_accuracy = 6;
	
	//toogle Draging function on double tap
	private long uptime = 0;
	private long tapdelay = 100;
	private long touchtime = 100;
	private boolean isDoubleTapAvailible = true;
	private boolean secondTap = false;
	
	


	public GameOfLiveView(Context context, DisplayMetrics dm, int cellsize) {
		super(context);
		this.context = context;
		this.cellsize = cellsize;
		setFocusable(true);

		mHolder = getHolder();
		mHolder.addCallback(this);
		mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);

		mCanvasThread = new GameOfLiveThread(this, new GameOfLiveRenderer(cellsize, dm));
		mCanvasThread.start();
		Toast.makeText(context, "Press Trackball/Center-Button for a step", Toast.LENGTH_LONG).show();
	}

	public void update(){
		updater.update(mCanvasThread, sleep);
	}


	//METHODS WHICH GET CALLED FROM THE ACTIVITY (MENU)
	public void toogleUpdates(){
		mCanvasThread.gameUpdates = !mCanvasThread.gameUpdates;
	}

	public void setSpeed(int speed){
		sleep = speed;
	}

	public void setCellsize(int cellsize){
		this.cellsize = cellsize;
		mCanvasThread.setCellsize(cellsize);
	}

	public boolean toogleEraser(){
		if(eraser)
			Toast.makeText(context, "Eraser is now off", Toast.LENGTH_SHORT).show();
		else
			Toast.makeText(context, "Eraser is now on", Toast.LENGTH_SHORT).show();
		return eraser = !eraser;

	}

	public void toogleInfo(){
		mCanvasThread.toogleInfo();
	}

	public void clear(){
		Toast.makeText(context, "Cleared stage", Toast.LENGTH_SHORT).show();
		mCanvasThread.gameUpdates = false;
		synchronized(mCanvasThread){
			mCanvasThread.resetGeneration();
			for (int i = 0; i < mCanvasThread.cells.length; i++) {
				for (int j = 0; j < mCanvasThread.cells[0].length; j++) {
					mCanvasThread.cells[i][j] = false;
				}
			}
		}
	}
	
	public void doZoom(int percent){
		mCanvasThread.getRenderer().doZoom(percent);
	}








	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int fx = ((int)event.getX());
		int fy = ((int)event.getY());
		int x = (int)(fx/(cellsize*mCanvasThread.getRenderer().zoomfactor));
		int y = (int)(fy/(cellsize*mCanvasThread.getRenderer().zoomfactor));
		if(event.getAction() == MotionEvent.ACTION_DOWN){
			downtime = System.currentTimeMillis();
			lastX = fx;
			lastY = fy;
			return true;
		}else
			if(event.getAction() == MotionEvent.ACTION_MOVE){
				
				if(getSpaceing(lastX, lastY, fx, fy) < movement_accuracy){ //Wenn sich der Finger kaum bewegt hat

					if((System.currentTimeMillis()-downtime)>longpressmillis && allowEreaseSwitch){//und eine gewisse zeit am screen war
						toogleEraser();
						allowEreaseSwitch = false;
					}
				}else
					allowEreaseSwitch = false;
				
				lastX=fx;
				lastY=fy;
				if(x < mCanvasThread.cells.length && y < mCanvasThread.cells[0].length){
					mCanvasThread.cells[x][y] = !eraser;
				}
			}else{
				if(event.getAction() == MotionEvent.ACTION_UP){
					allowEreaseSwitch=true;
					uptime = System.currentTimeMillis()-downtime;
					if(uptime < touchtime){
						if(!secondTap){
							secondTap = true;
						}else{
							secondTap = true;
							long firsttap = uptime+downtime;
							if((System.currentTimeMillis()-firsttap) < tapdelay){
								Log.d("Game of Life","DoubleTap");
							}
						}
					}
				}
			}
		return super.onTouchEvent(event);
	}

	private double getSpaceing(int x1, int y1, int x2, int y2){
		double x = x1-x2;
		double y = y1-y2;
		return Math.sqrt(x * x + y * y);

	}


	//PINCH ZOOMING FOR 2.0








	public SurfaceHolder getSurfaceHolder() {
		return mHolder;
	}



	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		if(mCanvasThread != null){
			mCanvasThread.surfaceCreated();
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		mCanvasThread.requestExitAndWait();
		mCanvasThread.surfaceDestroyed();
		mHolder.removeCallback(this);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

}
